﻿using System;
using System.Data;
using System.Drawing;
using System.Management;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.ComponentModel;
using Microsoft.ConfigurationManagement.ManagementProvider;
using Microsoft.ConfigurationManagement.ManagementProvider.WqlQueryEngine;
using Microsoft.ManagementConsole;
using System.DirectoryServices;
using System.Linq;
using System.Windows.Forms;
using Tools;
using System.ServiceProcess;

namespace InfraTools
{
    public class Sccm
    {
        public string SccmServer { get; set; }
        public string SccmUserName { get; set; }
        public string SccmPassword { get; set; } 
        public string SccmSiteCode {get ; set; }
        public string DomainName { get; set; }  
        public WqlConnectionManager SccmServerCon = new WqlConnectionManager();
        public ServiceController svcctrlWDS;
        private string colec;


        public Sccm()
        {
            SccmServer = Properties.Settings.Default.SccmServer;
            SccmUserName = Properties.Settings.Default.SccmUsr;
            SccmPassword = Properties.Settings.Default.SccmPwd;
            SccmSiteCode = Properties.Settings.Default.SccmSitecode;
            DomainName = Properties.Settings.Default.DomainName;
            svcctrlWDS = new ServiceController("WDSServer", SccmServer);
        }

        public Sccm(String sccmServer, String sccmUserName, String sccmPassword, String sccmSiteCode)

        {
            SccmServer   = sccmServer;
            SccmUserName = sccmUserName;
            SccmPassword = sccmPassword;
            SccmSiteCode = sccmSiteCode;
            DomainName = Properties.Settings.Default.DomainName;
            svcctrlWDS = new ServiceController("WDSServer", SccmServer);
        }



        //connector buider 
        public WqlConnectionManager Connect()
        {

            try
            {
                
                SmsNamedValuesDictionary namedValues = new SmsNamedValuesDictionary();
                WqlConnectionManager connection = new WqlConnectionManager(namedValues);

                connection.Connect(SccmServer, SccmUserName, SccmPassword);


                return connection;
            }
            catch (SmsException e)
            {
                Console.WriteLine("Failed to Connect. Error: " + e.Message);
                return null;
            }
            catch (UnauthorizedAccessException e)
            {
                Console.WriteLine("Failed to authenticate. Error:" + e.Message);
                return null;
            }
        }

        public void RestartWDS()
        {
            using (new Impersonator(SccmUserName, DomainName, SccmPassword))
            {
                try
                {
                    svcctrlWDS.Refresh();

                    if (svcctrlWDS.CanStop)
                    {
                        svcctrlWDS.Stop();
                        svcctrlWDS.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Stopped);

                    }


                    svcctrlWDS.Start();
                    svcctrlWDS.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Running);
                    MessageBox.Show("Service: " + svcctrlWDS.DisplayName + " restarted.");
                }
                catch (InvalidOperationException error)
                {
                    MessageBox.Show(error.Message);

                }
                catch (Win32Exception error)
                {
                    MessageBox.Show(error.Message);
                }
            }
        
        }

        public List<CmbObject> GetCollections()
        {
            try
            {
                // Get all the Collections
                ConnectionOptions opt = new ConnectionOptions();
                List<CmbObject> cmblst = new List<CmbObject>();


                opt.Username = SccmUserName;
                opt.Password = SccmPassword;

                ManagementScope scope =
                   new ManagementScope(
                       "\\\\" + SccmServer + "\\root\\SMS\\site_" + SccmSiteCode, opt);
                scope.Connect();

                //Query system for Operating System information

                ObjectQuery query = new ObjectQuery("Select * from SMS_Collection");
                ManagementObjectSearcher Collections = new ManagementObjectSearcher(scope, query);


                // Loop through each object (Collections) retrieved by WMI

                foreach (ManagementObject AbeCol in Collections.Get())
                {

                    // Add the Collections to the list (use the Name field as the item's caption)
                    CmbObject cmb = new CmbObject();
                    cmb.Comment = AbeCol["CollectionID"].ToString();
                    cmb.Name = AbeCol["Name"].ToString();
                    cmblst.Add(cmb);





                }

                return cmblst;
            }
            catch (Exception)
            {
                
                throw;
            }


        }

        public String GetSelectedCollection(string cmbselected)
        {

            try
            {
// Get all the Collections
            ConnectionOptions opt = new ConnectionOptions();
            ArrayList colls = new ArrayList();
            opt.Username = SccmUserName;
            opt.Password = SccmPassword;


            ManagementScope scope =
               new ManagementScope(
                   "\\\\" + SccmServer + "\\root\\SMS\\site_" + SccmSiteCode, opt);
            scope.Connect();

            //Query system for Operating System information

            ObjectQuery query = new ObjectQuery("Select * from SMS_Collection WHERE Name = '" + cmbselected + "'");
            ManagementObjectSearcher SmsCollection = new ManagementObjectSearcher(scope, query);
            // Get all the Collections from WMI that match the Collection  name selected in the ComboBox

            //ManagementObjectSearcher SmsCollection = new ManagementObjectSearcher();

            // Loop through the Collection retrieved, although it should normally be only one loop going on here

            //SccmCollection = ManagementObject SmsCollection["CollectionID"] 


            foreach (ManagementObject Col in SmsCollection.Get())
            {

                // Set all the fields to the appropriate values

                colls.Add(Col["CollectionID"].ToString());
                foreach (string coll in colls)
                {
                    colec = coll;


                }


            }

            return colec;
            }
            catch (Exception)
            {
                
                throw;
            }

        }

        public int AddNewComputer(string netBiosName, string smBiosGuid, string macAddress, string selcol)
        {
            try
            {
                if (smBiosGuid == null && macAddress == null)
                {
                    throw new ArgumentNullException("smBiosGuid or macAddress must be defined");
                }

                // Reformat macAddress to : separator.  
                if (string.IsNullOrEmpty(macAddress) == false)
                {
                    macAddress = macAddress.Replace("-", ":");
                }

                // Create the computer.  
                Dictionary<string, object> inParams = new Dictionary<string, object>();
                inParams.Add("NetbiosName", netBiosName);
                inParams.Add("SMBIOSGUID", smBiosGuid);
                inParams.Add("MACAddress", macAddress);
                inParams.Add("OverwriteExistingRecord", true);

                IResultObject outParams = SccmServerCon.ExecuteMethod("SMS_Site", "ImportMachineEntry", inParams);

                // Add to All System collection.  
                IResultObject collection = SccmServerCon.GetInstance("SMS_Collection.collectionId='" + selcol + "'");
                IResultObject collectionRule = SccmServerCon.CreateEmbeddedObjectInstance("SMS_CollectionRuleDirect");
                collectionRule["ResourceClassName"].StringValue = "SMS_R_System";
                collectionRule["ResourceID"].IntegerValue = outParams["ResourceID"].IntegerValue;

                Dictionary<string, object> inParams2 = new Dictionary<string, object>();
                inParams2.Add("collectionRule", collectionRule);

                collection.ExecuteMethod("AddMembershipRule", inParams2);

                return outParams["ResourceID"].IntegerValue;
            }
            catch (SmsException e)
            {
                MessageBox.Show("\nFailed to add the computer " + netBiosName + " Error: " + e.Message);
                return 0;
            }

        }

        public ArrayList SccmComputers(string Sccm_Collection)
        {
            try
            {
                ArrayList SccmComputers = new ArrayList();
                // Get all the Collections
                ConnectionOptions opt = new ConnectionOptions();
                ArrayList colls = new ArrayList();
                opt.Username = SccmUserName;
                opt.Password = SccmPassword;


                ManagementScope scope =
                   new ManagementScope(
                       "\\\\" + SccmServer + "\\root\\SMS\\site_" + SccmSiteCode, opt);
                scope.Connect();

                //Query system for Operating System information

                ObjectQuery query = new ObjectQuery("select Name from SMS_CM_RES_COLL_" + Sccm_Collection + " where IsActive = 'True'");
                ManagementObjectSearcher SmsPc = new ManagementObjectSearcher(scope, query);
                // Get all the PCs from WMI

                foreach (ManagementObject AbeCol in SmsPc.Get())
                {

                    // Add the Pc to the list 

                    SccmComputers.Add(AbeCol["Name"].ToString());




                }
                SccmComputers.Sort();

                return SccmComputers;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                throw;
            }



        }

        public ArrayList RemoveComputer(string hostname)
        {
            try
            {
 ArrayList SccmComputers = new ArrayList();
            // Get all the Collections
            ConnectionOptions opt = new ConnectionOptions();
            ArrayList colls = new ArrayList();
            opt.Username = SccmUserName;
            opt.Password = SccmPassword;


            ManagementScope scope =
               new ManagementScope(
                   "\\\\" + SccmServer + "\\root\\SMS\\site_" + SccmSiteCode, opt);
            scope.Connect();

            //Query system for Operating System information

            ObjectQuery query = new ObjectQuery("select * from SMS_R_System where NetbiosName =" + hostname);
            ManagementObjectSearcher SmsPc = new ManagementObjectSearcher(scope, query);
            // Get all the PCs from WMI

            foreach (ManagementObject PC in SmsPc.Get())
            {

                // Add the Pc to the list 

                MessageBox.Show(PC["Name"].ToString());
                //PC.Delete();



            }
            SccmComputers.Sort();

            return SccmComputers;


            }
            catch (Exception)
            {
                
                throw;
            }
        }

        public ArrayList GetfreePCName(string myADSPath, string adsfilter, string SccmCollection, ArrayList Glpipc)
        {

            
            ArrayList adpc = new ArrayList();
            ArrayList freepc = new ArrayList();
            ArrayList pclist = new ArrayList();
            ArrayList Sccmpclist = this.SccmComputers(SccmCollection);

            try
            {
                DirectoryEntry Ldap = new DirectoryEntry(myADSPath);
                Ldap.Username = SccmUserName;
                Ldap.Password = SccmPassword;
                DirectorySearcher searcher = new DirectorySearcher(Ldap);
                searcher.Filter = "(&(objectCategory=computer)(name=" + adsfilter + "*))";


                foreach (SearchResult result in searcher.FindAll())
                {
                    // On récupère l'entrée trouvée lors de la recherche
                    DirectoryEntry DirEntry = result.GetDirectoryEntry();

                    //On peut maintenant ajouter les informations désirées dans l'ArrayList

                    adpc.Add(DirEntry.Properties["cn"].Value);

                }

                for (int i = 0; i < int.Parse(Properties.Settings.Default.MaxNumPC) ; i++)
                {

                    pclist.Add(adsfilter + i.ToString().PadLeft(4, '0'));

                }



                adpc.Sort();

                foreach (String value in pclist)
                {

                    if (!adpc.Contains(value) && !Sccmpclist.Contains(value) && !Glpipc.Contains(value))
                    {
                        freepc.Add(value);

                    }
                }


            }



            catch (Exception Ex)
            {
                System.Windows.Forms.MessageBox.Show(Ex.Message, "Error adding Computer", MessageBoxButtons.OK);


            }

            return freepc;





        }

    }
}
